package utils

import (
	"encoding/json"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"time"
)

// LogLevel 日志级别
type LogLevel int

const (
	DEBUG LogLevel = iota
	INFO
	WARN
	ERROR
	FATAL
)

// logLevelNames 日志级别名称映射
var logLevelNames = map[LogLevel]string{
	DEBUG: "DEBUG",
	INFO:  "INFO",
	WARN:  "WARN",
	ERROR: "ERROR",
	FATAL: "FATAL",
}

// LogEntry 日志条目结构
type LogEntry struct {
	Timestamp string                 `json:"timestamp"`
	Level     string                 `json:"level"`
	Message   string                 `json:"message"`
	Data      map[string]interface{} `json:"data,omitempty"`
	File      string                 `json:"file,omitempty"`
	Line      int                    `json:"line,omitempty"`
	Function  string                 `json:"function,omitempty"`
}

// Logger 日志记录器
type Logger struct {
	level      LogLevel
	writers    []io.Writer
	enableFile bool
	logDir     string
	enableJSON bool
}

var defaultLogger *Logger

// InitLogger 初始化日志系统
func InitLogger() error {
	if AppConfig == nil {
		return fmt.Errorf("配置未初始化")
	}

	level := getLogLevelFromString(AppConfig.LogLevel)

	defaultLogger = &Logger{
		level:      level,
		writers:    []io.Writer{os.Stdout},
		enableFile: AppConfig.EnableLogging,
		logDir:     AppConfig.LogPath,
		enableJSON: true, // 默认使用JSON格式
	}

	// 如果启用文件日志，添加文件写入器
	if defaultLogger.enableFile {
		if err := defaultLogger.setupFileWriter(); err != nil {
			return fmt.Errorf("设置文件日志失败: %v", err)
		}
	}

	return nil
}

// setupFileWriter 设置文件写入器
func (l *Logger) setupFileWriter() error {
	// 确保日志目录存在
	if l.logDir == "" {
		l.logDir = "./logs/"
	}
	
	if err := os.MkdirAll(l.logDir, 0755); err != nil {
		return err
	}

	// 创建按日期命名的日志文件
	today := time.Now().Format("2006-01-02")
	logFile := filepath.Join(l.logDir, fmt.Sprintf("app-%s.log", today))

	file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		return err
	}

	l.writers = append(l.writers, file)
	return nil
}

// getLogLevelFromString 从字符串获取日志级别
func getLogLevelFromString(levelStr string) LogLevel {
	switch strings.ToUpper(levelStr) {
	case "DEBUG":
		return DEBUG
	case "INFO":
		return INFO
	case "WARN":
		return WARN
	case "ERROR":
		return ERROR
	case "FATAL":
		return FATAL
	default:
		return INFO
	}
}

// log 写入日志的核心方法
func (l *Logger) log(level LogLevel, message string, data map[string]interface{}) {
	if level < l.level {
		return
	}

	entry := LogEntry{
		Timestamp: time.Now().Format("2006-01-02 15:04:05.000"),
		Level:     logLevelNames[level],
		Message:   message,
		Data:      data,
	}

	// 获取调用信息
	if pc, file, line, ok := runtime.Caller(3); ok {
		entry.File = filepath.Base(file)
		entry.Line = line
		if f := runtime.FuncForPC(pc); f != nil {
			entry.Function = filepath.Base(f.Name())
		}
	}

	var output string
	if l.enableJSON {
		if jsonBytes, err := json.Marshal(entry); err == nil {
			output = string(jsonBytes)
		} else {
			output = fmt.Sprintf("%s [%s] %s", entry.Timestamp, entry.Level, entry.Message)
		}
	} else {
		output = fmt.Sprintf("%s [%s] %s:%d %s",
			entry.Timestamp, entry.Level, entry.File, entry.Line, entry.Message)
		if len(entry.Data) > 0 {
			if dataStr, err := json.Marshal(entry.Data); err == nil {
				output += " " + string(dataStr)
			}
		}
	}

	// 写入所有配置的输出
	for _, writer := range l.writers {
		fmt.Fprintln(writer, output)
	}
}

// Debug 记录调试信息
func Debug(message string, data ...map[string]interface{}) {
	if defaultLogger == nil {
		log.Printf("[DEBUG] %s", message)
		return
	}
	var logData map[string]interface{}
	if len(data) > 0 {
		logData = data[0]
	}
	defaultLogger.log(DEBUG, message, logData)
}

// Info 记录信息
func Info(message string, data ...map[string]interface{}) {
	if defaultLogger == nil {
		log.Printf("[INFO] %s", message)
		return
	}
	var logData map[string]interface{}
	if len(data) > 0 {
		logData = data[0]
	}
	defaultLogger.log(INFO, message, logData)
}

// Warn 记录警告
func Warn(message string, data ...map[string]interface{}) {
	if defaultLogger == nil {
		log.Printf("[WARN] %s", message)
		return
	}
	var logData map[string]interface{}
	if len(data) > 0 {
		logData = data[0]
	}
	defaultLogger.log(WARN, message, logData)
}

// Error 记录错误
func Error(message string, data ...map[string]interface{}) {
	if defaultLogger == nil {
		log.Printf("[ERROR] %s", message)
		return
	}
	var logData map[string]interface{}
	if len(data) > 0 {
		logData = data[0]
	}
	defaultLogger.log(ERROR, message, logData)
}

// Fatal 记录致命错误
func Fatal(message string, data ...map[string]interface{}) {
	if defaultLogger == nil {
		log.Fatalf("[FATAL] %s", message)
		return
	}
	var logData map[string]interface{}
	if len(data) > 0 {
		logData = data[0]
	}
	defaultLogger.log(FATAL, message, logData)
	os.Exit(1)
}

// LogError 记录错误对象
func LogError(err error, message string, data ...map[string]interface{}) {
	if err == nil {
		return
	}

	logData := make(map[string]interface{})
	if len(data) > 0 && data[0] != nil {
		logData = data[0]
	}
	logData["error"] = err.Error()

	Error(message, logData)
}

// LogRequest 记录HTTP请求
func LogRequest(method, path, userAgent, clientIP string, statusCode int, duration time.Duration) {
	Info("HTTP Request", map[string]interface{}{
		"method":      method,
		"path":        path,
		"user_agent":  userAgent,
		"client_ip":   clientIP,
		"status_code": statusCode,
		"duration_ms": duration.Milliseconds(),
	})
}

// LogUserAction 记录用户操作
func LogUserAction(userSN, action, resource string, data map[string]interface{}) {
	logData := map[string]interface{}{
		"user_sn":  userSN,
		"action":   action,
		"resource": resource,
	}

	// 合并额外数据
	for k, v := range data {
		logData[k] = v
	}

	Info("User Action", logData)
}
